package com.gopay.checkorder.service.impl;

import java.math.BigDecimal;
import java.util.List;

import javax.annotation.Resource;

import com.gopay.common.util.DateUtils;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.checkorder.service.BankOrderService;
import com.gopay.checkorder.service.task.BankCountDownLatch;
import com.gopay.common.Result;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.BisBankInterfaceChannel;
import com.gopay.common.constants.bank.CcbConstants;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.domain.bank.BankOrder;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.ccb.ebank.pay.CcbB2cMessage;
import com.gopay.common.domain.bank.dayend.BaseDayendEntry;
import com.gopay.common.domain.cashier.BankCardType;
import com.gopay.common.domain.cps.vo.CheckOrderResult;
import com.gopay.common.domain.cps.vo.InAccInfo;
import com.gopay.common.util.TransUtil;
import com.gopay.remote.bank.BankInteractRemoteService;

/**
 * @CheckOrderCcbB2cImpl.java
 * @author wanggang
 * @2013-11-15 下午4:14:05 www.gopay.com.cn Inc.All rights reserved.
 */
public class CheckOrderCcbB2cImpl implements BankOrderService {

	private final static Logger logger = LoggerFactory.getLogger("CCB");

	@Resource(name = "bankClient")
	private BankInteractRemoteService bankClient;
	@Override
	public CheckOrderResult checkOrder(BankOrder bankOrder, String target) {
		CheckOrderResult checkOrderResult = new CheckOrderResult();
		checkOrderResult.setSuccess(false);
		checkOrderResult.setOrderId(bankOrder.getOrderId());
		try {
			CcbB2cMessage base = new CcbB2cMessage();
			if (TransUtil.getCurrentDateStr().equals(DateUtils.date2string(bankOrder.getSendBankTm(),"yyyyMMdd"))) {
				base.setKind("0"); // 0:未结算流水 1:已结算流水
			} else {
				base.setKind("1"); // 0:未结算流水 1:已结算流水
			}
			base.setOrder(bankOrder.getOutOrderId()); // 订单号已经换了另外字段,并且是为了按时间段查询
			base.setOrderId(bankOrder.getOrderId());
			base.setBankOrderId(bankOrder.getOutOrderId());
			base.setBank(BankConstants.BANK_LOGO_CCB);
			base.setBankIntrChann(BisBankInterfaceChannel.get(bankOrder.getInterfaceChennelCode()));
			base.setBankBusProd(BisBankBusinessProd.get(bankOrder.getBankBizProdCode()));
			Result result = new Result();
			result = bankClient.query(base);

			if (result == null || !result.isSuccess() || result.getDefaultModel() == null) {
				logger.error("bankClient fail.");

				if(result ==null || ProcCodeConstants.PROC_CODE_100E6037.equals(result.getResultCode())){
					BankCountDownLatch.failIncrease(bankOrder.getBankCode());
					checkOrderResult.setCommunicateError(true);
				}
				logger.error(ToStringBuilder.reflectionToString(result,ToStringStyle.DEFAULT_STYLE));
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("系统返回对账结果为空");
				return checkOrderResult;
			}

			CcbB2cMessage res = (CcbB2cMessage) result.getDefaultModel();
			if (res == null) {
				// 查询订单为空
				logger.error("fail:orderId:" + bankOrder.getOrderId()+ " errcode:" + ProcCodeConstants.PROC_CODE_100E6022+ " err:bis query is null.");
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
				checkOrderResult.setErrMsg("银行返回对账结果为空");
				return checkOrderResult;
			}

			if (StringUtils.isNotBlank(res.getReturnCode()) && "0".equals(res.getReturnCode())) {
				// 查询订单错误
				logger.error("fail:orderId:" + bankOrder.getOrderId()+ " errcode:" + res.getReturnCode() + " err:"+ res.getReturnMsg());
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg(res.getReturnMsg());
				return checkOrderResult;
			}

			// 查询成功才进行下面开发
			if (StringUtils.equals(CcbConstants.CCB_SUCCESS,res.getReturnCode())) {
				String orderStatus = res.getStatus();
				//失败处理
				if (StringUtils.equals(CcbConstants.B2C_QUERY_FAIL, orderStatus)) {
					checkOrderResult.setBankFailure(true);
					checkOrderResult.setErrMsg("银行返回交易失败");
					logger.info("建行B2C订单" + res.getOrder() + "的交易失败");
				}
				//成功处理
				else if (StringUtils.equals(CcbConstants.B2C_QUERY_SUCC,orderStatus)) {
					logger.info("建行B2C订单" + res.getOrder() + "的交易成功");
					checkOrderResult.setErrMsg("银行返回交易成功");
					checkOrderResult.setSuccess(true);
					InAccInfo accInfo = new InAccInfo();
					accInfo.setOrderId(bankOrder.getOrderId());
					accInfo.setAmount(new BigDecimal(res.getPaymentMoney()));
					accInfo.setRetCode("00");
					accInfo.setCardType(BankCardType.Unknown.toString());
					checkOrderResult.setAccInfo(accInfo);
				}
				//不处理
				else if (StringUtils.equals(CcbConstants.B2C_QUERY_NEEDCONFIRM, orderStatus)) {
					logger.info("建行B2C订单" + res.getOrder() + "的交易待银行确认");
					checkOrderResult.setErrMsg("银行返回交易待确认");
				} else if (StringUtils.equals(CcbConstants.B2C_QUERY_SOME_REFUNDMENT, orderStatus)) {
					logger.info("建行B2C订单" + res.getOrder() + "的交易部分退款");
					checkOrderResult.setErrMsg("银行返回交易部分退款");
				} else if (StringUtils.equals(CcbConstants.B2C_QUERY_ALL_REFUNDMENT, orderStatus)) {
					logger.info("建行B2C订单" + res.getOrder() + "的交易全部退款");
					checkOrderResult.setErrMsg("银行返回交易全部退款");
				} else {
					logger.info("建行B2C订单" + res.getOrder() + "的交易发生未明情况");
					checkOrderResult.setErrMsg("银行返回交易未明情况");
				}
			} else if (StringUtils.equals(CcbConstants.CCB_ORDER_NOTFOUND,res.getReturnCode())) {
				logger.info("建行B2C订单查询未查到订单，返回码： " + res.getReturnCode()+ "，返回描述：" + res.getReturnMsg() + "订单号："+ res.getOrder());
				checkOrderResult.setErrMsg("银行返回交易未查到");
			} else {
				logger.info("建行B2C订单查询返回码异常，查询订单失败，返回码： " + res.getReturnCode()+ "，返回描述：" + res.getReturnMsg() + "订单号："+ res.getOrder());
				checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E5062);
				checkOrderResult.setErrMsg("银行返回订单查询失败");
			}
			return checkOrderResult;

		} catch (Exception e) {
			logger.error("bankClient fail.", e);
			checkOrderResult.setErrCode(ProcCodeConstants.PROC_CODE_100E6022);
			checkOrderResult.setErrMsg("银行对账异常");
			return checkOrderResult;
		}
	}
	@Override
	public BankOrder getDbOrder() {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public BaseMessage dayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public List<CheckOrderResult> checkDayend(String bank_bus) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public Result getDayendMsg(String string) {
		// TODO Auto-generated method stub
		return null;
	}
	@Override
	public CheckOrderResult checkDayendOrder(BaseDayendEntry bdm, BankOrder bo) {
		// TODO Auto-generated method stub
		return null;
	}
}
